package service

import (
	"context"
	"errors"
	"strconv"
	"strings"
	"time"

	"gitee.com/daonna/collab-manage-system/ent"
	"gitee.com/daonna/collab-manage-system/ent/actreview"
	"gitee.com/daonna/collab-manage-system/repository/db"
)

type CreateActivityReviewInput struct {
	Rating      int      `json:"rating" binding:"required,min=1,max=5"`
	Content     string   `json:"content"`
	IsAnonymous bool     `json:"is_anonymous"`
	ImageUrls   []string `json:"image_urls"`
}

type UpdateActivityReviewInput struct {
	Rating      *int      `json:"rating"`
	Content     *string   `json:"content"`
	IsAnonymous *bool     `json:"is_anonymous"`
	ImageUrls   *[]string `json:"image_urls"`
}

type AdminReplyInput struct {
	AdminReply string `json:"admin_reply" binding:"required"`
}

type DeleteActivityReviewInput struct {
	ReviewID string `json:"review_id" binding:"required"`
}

// CreateActivityReview 创建一个活动评价
func CreateActivityReview(ctx context.Context, currentUserID uint, activityID string, input CreateActivityReviewInput) (*ent.ActReview, error) {
	dbClient := db.GetDBClient()

	activityIDInt, err := strconv.ParseInt(activityID, 10, 64)
	if err != nil {
		return nil, errors.New("无效的活动ID")
	}

	// 检查用户是否已经评价过该活动
	exists, err := dbClient.ActReview().ActReview.Query().
		Where(
			actreview.ActivityID(activityIDInt),
			actreview.UserID(int64(currentUserID)),
			actreview.StatusEQ(actreview.StatusActive),
		).Exist(ctx)
	if err != nil {
		return nil, err
	}
	if exists {
		return nil, errors.New("您已经评价过该活动")
	}

	// 处理图片URL，将数组转换为逗号分隔的字符串
	var imageUrlsStr string
	if len(input.ImageUrls) > 0 {
		imageUrlsStr = strings.Join(input.ImageUrls, ",")
	}

	// 创建评价
	review, err := dbClient.ActReview().ActReview.Create().
		SetActivityID(activityIDInt).
		SetUserID(int64(currentUserID)).
		SetRating(input.Rating).
		SetContent(input.Content).
		SetIsAnonymous(input.IsAnonymous).
		SetNillableImageUrls(func() *string {
			if imageUrlsStr != "" {
				return &imageUrlsStr
			}
			return nil
		}()).
		SetStatus(actreview.StatusActive).
		Save(ctx)

	if err != nil {
		return nil, err
	}

	return review, nil
}

// ListActivityReviews 获取活动的评价列表
func ListActivityReviews(ctx context.Context, activityID string) ([]*ent.ActReview, error) {
	dbClient := db.GetDBClient()

	activityIDInt, err := strconv.ParseInt(activityID, 10, 64)
	if err != nil {
		return nil, errors.New("无效的活动ID")
	}

	// 查询活动的所有有效评价
	reviews, err := dbClient.ActReview().ActReview.Query().
		Where(
			actreview.ActivityID(activityIDInt),
			actreview.StatusEQ(actreview.StatusActive),
		).
		Order(ent.Desc(actreview.FieldCreatedAt)).
		WithUser().
		WithActivity().
		All(ctx)

	if err != nil {
		return nil, err
	}

	return reviews, nil
}

// UpdateActivityReview 更新活动评价
func UpdateActivityReview(ctx context.Context, currentUserID uint, activityID string, reviewID string, input UpdateActivityReviewInput) (*ent.ActReview, error) {
	dbClient := db.GetDBClient()

	reviewIDInt, err := strconv.ParseInt(reviewID, 10, 64)
	if err != nil {
		return nil, errors.New("无效的评价ID")
	}

	// 查询评价并验证所有权
	review, err := dbClient.ActReview().ActReview.Query().
		Where(
			actreview.ID(reviewIDInt),
			actreview.StatusEQ(actreview.StatusActive),
		).First(ctx)

	if err != nil {
		if ent.IsNotFound(err) {
			return nil, errors.New("评价不存在")
		}
		return nil, err
	}

	// 验证用户是否有权限更新评价
	if review.UserID != int64(currentUserID) {
		return nil, errors.New("您没有权限更新此评价")
	}

	// 构建更新操作
	updateQuery := dbClient.ActReview().ActReview.UpdateOneID(reviewIDInt)

	if input.Rating != nil {
		if *input.Rating < 1 || *input.Rating > 5 {
			return nil, errors.New("评分必须在1-5之间")
		}
		updateQuery.SetRating(*input.Rating)
	}

	if input.Content != nil {
		updateQuery.SetContent(*input.Content)
	}

	if input.IsAnonymous != nil {
		updateQuery.SetIsAnonymous(*input.IsAnonymous)
	}

	if input.ImageUrls != nil {
		imageUrlsStr := strings.Join(*input.ImageUrls, ",")
		updateQuery.SetImageUrls(imageUrlsStr)
	}

	// 执行更新
	updatedReview, err := updateQuery.Save(ctx)
	if err != nil {
		return nil, err
	}

	return updatedReview, nil
}

// AdminReplyReview 管理员回复评价
func AdminReplyReview(ctx context.Context, activityID string, reviewID string, input AdminReplyInput) (*ent.ActReview, error) {
	dbClient := db.GetDBClient()

	reviewIDInt, err := strconv.ParseInt(reviewID, 10, 64)
	if err != nil {
		return nil, errors.New("无效的评价ID")
	}

	// 更新评价，添加管理员回复
	updatedReview, err := dbClient.ActReview().ActReview.UpdateOneID(reviewIDInt).
		SetAdminReply(input.AdminReply).
		SetRepliedAt(time.Now()).
		Save(ctx)

	if err != nil {
		if ent.IsNotFound(err) {
			return nil, errors.New("评价不存在")
		}
		return nil, err
	}

	return updatedReview, nil
}

// DeleteActivityReview 删除活动评价
func DeleteActivityReview(ctx context.Context, currentUserID uint, activityID string, reviewID string) error {
	dbClient := db.GetDBClient()

	reviewIDInt, err := strconv.ParseInt(reviewID, 10, 64)
	if err != nil {
		return errors.New("无效的评价ID")
	}

	// 查询评价并验证所有权
	review, err := dbClient.ActReview().ActReview.Get(ctx, reviewIDInt)
	if err != nil {
		if ent.IsNotFound(err) {
			return errors.New("评价不存在")
		}
		return err
	}

	// 验证用户是否有权限删除评价
	if review.UserID != int64(currentUserID) {
		return errors.New("您没有权限删除此评价")
	}

	// 软删除评价 (将状态更改为deleted)
	_, err = dbClient.ActReview().ActReview.UpdateOneID(reviewIDInt).
		SetStatus(actreview.StatusDeleted).
		Save(ctx)

	return err
}

// GetActivityReview 获取单个活动评价
func GetActivityReview(ctx context.Context, activityID string, reviewID string) (*ent.ActReview, error) {
	dbClient := db.GetDBClient()

	reviewIDInt, err := strconv.ParseInt(reviewID, 10, 64)
	if err != nil {
		return nil, errors.New("无效的评价ID")
	}

	activityIDInt, err := strconv.ParseInt(activityID, 10, 64)
	if err != nil {
		return nil, errors.New("无效的活动ID")
	}

	// 查询指定评价
	review, err := dbClient.ActReview().ActReview.Query().
		Where(
			actreview.ID(reviewIDInt),
			actreview.ActivityID(activityIDInt),
			actreview.StatusEQ(actreview.StatusActive),
		).
		WithUser().
		WithActivity().
		First(ctx)

	if err != nil {
		if ent.IsNotFound(err) {
			return nil, errors.New("评价不存在")
		}
		return nil, err
	}

	return review, nil
}

// GetUserActivityReviews 获取用户的所有活动评价
func GetUserActivityReviews(ctx context.Context, userID uint) ([]*ent.ActReview, error) {
	dbClient := db.GetDBClient()

	// 查询用户的所有有效评价
	reviews, err := dbClient.ActReview().ActReview.Query().
		Where(
			actreview.UserID(int64(userID)),
			actreview.StatusEQ(actreview.StatusActive),
		).
		Order(ent.Desc(actreview.FieldCreatedAt)).
		WithActivity().
		All(ctx)

	if err != nil {
		return nil, err
	}

	return reviews, nil
}
